#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <net/ethernet.h>
#include <arpa/inet.h>
#include <string.h>
#include <strings.h>
#include <sys/types.h>
#include <pthread.h>
#include <net/if_arp.h>
#include <linux/ip.h>


#include "network_interface.h"
#include "main.h"
#include "arp_link.h"
#include "arp_pthread.h"
#include "ip_pthread.h"


void send_ping_func(char * dest_ip);

int main(int argc, char const *argv[])
{
    //1. 遍历所有的网卡信息
    scan_all_interface();



    // 2. 创建原始套接字，接收所有类型的数据包
    raw_socketfd  = socket(PF_PACKET , SOCK_RAW , htons(ETH_P_ALL));

    if(raw_socketfd < 0){
        perror("socket");
		_exit(-1);
    }

    unsigned char recv_buf[RECV_SIZE] = {0}; // 原始套接字数据包大约1500字节
    ssize_t recv_len = 0;
    while (1)
    {
        bzero(recv_buf, sizeof(recv_buf));
        // 接受网卡上所有数据包
        recv_len = recvfrom(raw_socketfd , recv_buf , sizeof(recv_buf) , 0, NULL , NULL);

        // 长度异常， 重新接收
        if(recv_len<=0||recv_len>RECV_SIZE){
			perror("recvfrom");
			continue;
		}

        // 解析数据包
        // ARP 协议包解析
        if( (recv_buf[12] == 0x08 ) && ( recv_buf[13] == 0x06) )
        {
            ARP_LINK* p_arp_node = (ARP_LINK*) malloc(sizeof(ARP_LINK)); // 堆上创建arp 节点
            if (p_arp_node == NULL)
            {
                perror("malloc");
                continue;
            }
            
            // 将arp请求中的来源 ip和mac 封装成 arp_link 节点
            memcpy(p_arp_node->mac , recv_buf + 22 , 6);  // 源mac
            memcpy(p_arp_node->ip , recv_buf + 28 , 4 );     // 源ip
            // 测试打印arp接受的 元ip
            // printf("main: arp->src_ip:%d.%d.%d.%d\n", p_arp_node->ip[0], p_arp_node->ip[1],p_arp_node->ip[2],p_arp_node->ip[3]);

            // 创建线程，处理arp请求相关操作
            pthread_t arp_pid;
            pthread_create(&arp_pid ,NULL, arp_pthread , (void *) p_arp_node );
            pthread_detach(arp_pid);
        }

        // IP协议包
        if( (recv_buf[12] == 0x08) && (recv_buf[13] == 0x00 ) )  // mac头的 协议类型
        {
            struct iphdr *ip = (struct iphdr *) (recv_buf + 14);
            // if (ip->protocol == IPPROTO_ICMP) {
            //     struct icmphdr *icmp = (struct icmphdr *)(packet + sizeof(struct iphdr));
            //     printf("Received ICMP packet from %s\n", inet_ntoa(addr.sin_addr));
            // }

            if(ip->protocol == IPPROTO_ICMP)
            {

                // 目的ip过滤（暂时不做）

                // 堆上创建自定义的结构体接受收到的数据 , 以便后续线程处理 （复制一份）
                RECV_DATA * stru_recv = (RECV_DATA *)malloc(sizeof(RECV_DATA));
                stru_recv->data_len = recv_len;
                memcpy(stru_recv->data , recv_buf , recv_len);

                // char * p_src_ip =  (char *)(&ip->saddr);
                // unsigned char* p_dst_ip =  (unsigned char *)(&ip->daddr);
                

                // 创建转发数据包处理线程
                pthread_t ip_pid;
                pthread_create(&ip_pid , NULL , ip_pthread_handler  , (void *)stru_recv );
                pthread_detach(ip_pid);

            }
           
        }


    }
    





    // 结束程序，释放所有的堆上分配的arp链表节点
    // free_all_arp_link();


    return 0;
}



